from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.utils import timezone
from datetime import datetime, timedelta
from calendar import monthrange
from django.db.models import Q
from staff.models import Employee
from .models import AttendanceRecord
from .serializers import MonthlyAttendanceResponseSerializer


class MonthlyAttendanceView(APIView):
    """月度考勤查询接口，年月由前端操作传递，支持工号/姓名查询"""

    def get(self, request):
        employee_id = request.query_params.get('employee_id')  # 工号（用户输入）
        employee_name = request.query_params.get('name')  # 姓名（用户输入）
        year = request.query_params.get('year')  # 年份（前端操作传递）
        month = request.query_params.get('month')  # 月份（前端操作传递）

        # 2. 参数验证
        if not (employee_id or employee_name):
            return Response(
                {"error": "请提供员工工号或姓名"},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 验证年月参数（必须由前端传递，且格式正确）
        if not all([year, month]):
            return Response(
                {"error": "年月参数缺失，请通过前端界面选择月份"},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            year = int(year)
            month = int(month)
            if month < 1 or month > 12:
                raise ValueError("月份必须在1-12之间")
            current_year = datetime.now().year
            if year < current_year - 5 or year > current_year + 1:
                raise ValueError(f"年份超出查询范围（{current_year - 5}至{current_year + 1}）")
        except ValueError as e:
            return Response(
                {"error": f"年月格式错误：{str(e)}"},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:

            query = Q()
            if employee_id:
                query |= Q(work_id=employee_id)
            if employee_name:
                query |= Q(name__icontains=employee_name)

            employees = Employee.objects.filter(query)
            if not employees.exists():
                raise Employee.DoesNotExist(f"未找到工号为{employee_id}或姓名包含{employee_name}的员工")
            if employees.count() > 1:
                return Response(
                    {"error": f"找到多个姓名包含{employee_name}的员工，请使用工号精确查询"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            employee = employees.first()

        except Employee.DoesNotExist as e:
            return Response(
                {"error": str(e)},
                status=status.HTTP_404_NOT_FOUND
            )

        start_date = datetime(year, month, 1).date()
        end_day = monthrange(year, month)[1]
        end_date = datetime(year, month, end_day).date()
        date_range = f"{start_date.strftime('%Y-%m-%d')}至{end_date.strftime('%Y-%m-%d')}"

        # 计算工作日总数
        work_days = 0
        current_date = start_date
        while current_date <= end_date:
            if current_date.weekday() < 5:  # 周一至周五为工作日
                work_days += 1
            current_date += timedelta(days=1)

        # 查询当月考勤记录并转换为映射
        attendance_records = AttendanceRecord.objects.filter(
            employee=employee,
            record_date__gte=start_date,
            record_date__lte=end_date
        )
        attendance_map = {
            record.record_date.strftime("%Y-%m-%d"): record
            for record in attendance_records
        }

        # 生成日历数据和统计指标
        calendar_days = []
        normal_count = late_count = early_leave_count = 0
        missing_card_count = absent_count = leave_count = 0
        business_trip_count = total_late_minutes = 0

        current_date = start_date
        while current_date <= end_date:
            date_str = current_date.strftime("%Y-%m-%d")
            weekday = current_date.weekday()
            weekday_str = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"][weekday]

            day_data = {
                "date": current_date,
                "weekday": weekday_str,
                "status": "",
                "status_display": "",
                "check_in": None,
                "check_out": None,
                "note": ""
            }

            # 处理周末
            if weekday >= 5:
                day_data["status"] = "weekend"
                day_data["status_display"] = "周末"
                calendar_days.append(day_data)
                current_date += timedelta(days=1)
                continue

            # 处理工作日考勤
            record = attendance_map.get(date_str)
            if not record:
                day_data["status"] = "absent"
                day_data["status_display"] = "旷工"
                absent_count += 1
            else:
                status_map = {
                    "正常": "normal", "迟到": "late", "早退": "early_leave",
                    "缺上班卡": "missing_card", "缺下班卡": "missing_card",
                    "旷工": "absent", "请假": "leave", "出差": "business_trip"
                }
                day_data["status"] = status_map.get(record.status, "unknown")
                day_data["status_display"] = record.status
                day_data["check_in"] = record.check_in_time.time() if record.check_in_time else None
                day_data["check_out"] = record.check_out_time.time() if record.check_out_time else None
                day_data["note"] = record.correction_note if record.is_corrected else ""

                # 更新统计
                if record.status == "正常":
                    normal_count += 1
                elif record.status == "迟到":
                    late_count += 1
                    total_late_minutes += record.late_minutes
                elif record.status == "早退":
                    early_leave_count += 1
                elif record.status in ["缺上班卡", "缺下班卡"]:
                    missing_card_count += 1
                elif record.status == "旷工":
                    absent_count += 1
                elif record.status == "请假":
                    leave_count += 1
                elif record.status == "出差":
                    business_trip_count += 1

            calendar_days.append(day_data)
            current_date += timedelta(days=1)

        # 计算汇总指标
        actual_attendance_days = normal_count + late_count + early_leave_count
        attendance_rate = round(actual_attendance_days / work_days * 100, 1) if work_days > 0 else 0
        abnormal_count = late_count + early_leave_count + missing_card_count

        # 组装并返回数据
        response_data = {
            "employee": employee,
            "summary": {
                "year": year,
                "month": month,
                "date_range": date_range,
                "work_days": work_days,
                "attendance_rate": attendance_rate,
                "normal_count": normal_count,
                "abnormal_count": abnormal_count,
                "late_count": late_count,
                "late_total_minutes": total_late_minutes,
                "early_leave_count": early_leave_count,
                "missing_card_count": missing_card_count,
                "absent_count": absent_count,
                "leave_count": leave_count,
                "business_trip_count": business_trip_count
            },
            "calendar": calendar_days
        }

        serializer = MonthlyAttendanceResponseSerializer(response_data)
        return Response(serializer.data)


class AttendanceDetailView(APIView):

    def get(self, request):
        employee_id = request.query_params.get('employee_id')
        employee_name = request.query_params.get('name')
        date = request.query_params.get('date')

        # 参数验证
        if not (employee_id or employee_name):
            return Response(
                {"error": "请提供员工工号（employee_id）或姓名（name）"},
                status=status.HTTP_400_BAD_REQUEST
            )
        if not date:
            return Response(
                {"error": "日期参数缺失，请通过前端界面选择日期"},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            # 解析日期（前端传递的格式必须正确）
            record_date = datetime.strptime(date, "%Y-%m-%d").date()

            # 查询员工
            query = Q()
            if employee_id:
                query |= Q(work_id=employee_id)
            if employee_name:
                query |= Q(name__icontains=employee_name)

            employees = Employee.objects.filter(query)
            if not employees.exists():
                raise Employee.DoesNotExist(f"未找到匹配的员工")
            if employees.count() > 1:
                return Response(
                    {"error": "找到多个匹配员工，请使用工号查询"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            employee = employees.first()

            # 获取考勤记录
            record = AttendanceRecord.objects.get(employee=employee, record_date=record_date)

        except (ValueError, Employee.DoesNotExist, AttendanceRecord.DoesNotExist) as e:
            return Response(
                {"error": f"获取考勤详情失败：{str(e)}"},
                status=status.HTTP_404_NOT_FOUND
            )

        # 刷新考勤状态
        record.calculate_status()
        record.save()

        from .serializers import AttendanceDetailSerializer
        serializer = AttendanceDetailSerializer(record)
        return Response(serializer.data)
